package com.lv.leyou.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lv.leyou.common.dto.PageDTO;
import com.lv.leyou.common.exception.LyException;
import com.lv.leyou.dto.SkuDTO;
import com.lv.leyou.dto.SpuDTO;
import com.lv.leyou.dto.SpuDetailDTO;
import com.lv.leyou.entity.*;
import com.lv.leyou.mapper.SpuMapper;
import com.lv.leyou.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.stream.Collectors;

@Service
public class SpuServiceImpl extends ServiceImpl<SpuMapper, Spu> implements SpuService {
    @Autowired
    private BrandService brandService;
    @Autowired
    private CategoryService categoryService;
    @Autowired
    private SkuService skuService;
    @Autowired
    private SpuDetailService spuDetailService;
    @Override
    public PageDTO<SpuDTO> pageSpu(Long page, Long rows,Long brandId,Long categoryId,Long id,Boolean saleable) {
        QueryWrapper<Spu> queryWrapper = new QueryWrapper<>();
        // 2.准备查询条件， SELECT * FROM tb_spu WHERE saleable = ? AND category_id = ?
        // AND brand_id = ? AND id = ?
        queryWrapper.eq(id != null, "id", id).eq(brandId != null, "brand_id", brandId)
                .eq(categoryId != null, "cid3", categoryId)
                .eq(saleable != null, "saleable", saleable);

        Page<Spu> spuPage =page(new Page<>(page,rows),queryWrapper);

        List<Spu> records = spuPage.getRecords();
        List<SpuDTO> spuDTOS = SpuDTO.convertEntityList(records);
        long total = spuPage.getTotal();
        long pages = spuPage.getPages();
        //查询spu的分类和品牌名称
        for (SpuDTO spuDTO : spuDTOS) {
            Long brandId1 = spuDTO.getBrandId();
            //根据品牌id，查询品牌名称
            Brand byId = brandService.getById(brandId1);
            if (byId != null) {
                String name = byId.getName();
                spuDTO.setBrandName(name);
            }

            //根据分类id，查询分类.得到的有三级分类id，分别根据这些id到分类表中查找对应的分类名称
            List<Long> categoryIds = spuDTO.getCategoryIds();
            List<Category> categories = categoryService.listByIds(categoryIds);
            if (!CollectionUtils.isEmpty(categories)) {
                //取出分类名称，拼接起来
                String names = categories.stream().map(Category::getName).collect(Collectors.joining("/"));
                spuDTO.setCategoryName(names);
            }

        }
        //封装结果并返回
        PageDTO<SpuDTO> spuDTOPageDTO = new PageDTO<>();
        spuDTOPageDTO.setTotal(total);
        spuDTOPageDTO.setTotalPage(pages);
        spuDTOPageDTO.setItems(spuDTOS);
        return spuDTOPageDTO;
    }
    //新增商品
    @Transactional
    @Override
    public void addSpu(SpuDTO spuDTO) {
        Spu spu = spuDTO.toEntity(Spu.class);
        List<SkuDTO> skus = spuDTO.getSkus();
        if (CollectionUtils.isEmpty(skus)) {
            throw new LyException(500,"每个spu下至少有一个sku");
        }
        //保存spu,同时主键回显
        save(spu);
        //获取spu的id
        Long spuId = spu.getId();
        //根据spuId查询对应的spuDetail详情
        SpuDetail spudetail = spuDetailService.getById(spuId);
        boolean save = spuDetailService.save(spudetail);
        if (!save) {
            throw new LyException(500, "新增商品详细失败");
        }
        //新增sku
        //根据spuid查询对应的sku详情
        List<Sku> skuList = skuService.query().eq("spu_id", spuId).list();
        for (Sku sku : skuList) {
            sku.setId(spuId);
            sku.setSaleable(true);
        }
        skuService.saveBatch(skuList);
    }

    @Override
    public SpuDTO querySpuDto(Long id) {
        Spu spu = getById(id);
        if (spu == null) {
            throw new LyException(400,"商品id不存在");
        }
        SpuDTO spuDTO = new SpuDTO(spu);
        //根据spuId查询对应的spuDetail详情
        SpuDetail spudetail = spuDetailService.getById(id);
        if (spudetail == null) {
            throw new LyException(400,"商品id不存在");
        }
        SpuDetailDTO spuDetailDTO = new SpuDetailDTO(spudetail);
        spuDTO.setSpuDetail(spuDetailDTO);
        //根据spuid查询对应的sku详情
        List<Sku> skuList = skuService.query().eq("spu_id", id).list();
        if (CollectionUtils.isEmpty(skuList)) {
            throw new LyException(400,"商品id不存在");
        }
        List<SkuDTO> skuDTOS = SkuDTO.convertEntityList(skuList);
        spuDTO.setSkus(skuDTOS);
        // 根据品牌id查询品牌名称
        Brand brand = brandService.getById(spuDTO.getBrandId());
        if(brand != null) {
            spuDTO.setBrandName(brand.getName());
        }
        // 根据三级分类id查询分类集合
        List<Category> categories = categoryService.listByIds(spuDTO.getCategoryIds());
        if(!CollectionUtils.isEmpty(categories)) {
            // 取出分类的名称，拼接起来
            String names = categories.stream().map(Category::getName).collect(Collectors.joining("/"));
            spuDTO.setCategoryName(names);
        }

        return spuDTO;
    }

    @Override
    public SpuDetailDTO querySpecDetail(Long id) {
        SpuDetail spuDetail = spuDetailService.getById(id);
        SpuDetailDTO spuDetailDTO = new SpuDetailDTO(spuDetail);
        return spuDetailDTO;
    }

    @Override
    public List<SkuDTO> querySkulistBySpuid(Long id) {
        List<Sku> skuList = skuService.query().eq("spu_id", id).list();
        List<SkuDTO> skuDTOS = SkuDTO.convertEntityList(skuList);

        return skuDTOS;
    }

    @Override
    public List<SkuDTO> querySkuList(List<Long> ids) {
        List<Sku> skuList = skuService.listByIds(ids);
        List<SkuDTO> collect = skuList.stream().map(SkuDTO::new).collect(Collectors.toList());
        return collect;
    }

    @Override
    public SpuDTO querySkuById(Long id) {
        Spu spu = getById(id);
        SpuDTO spuDTO = new SpuDTO(spu);

        return spuDTO;
    }

    @Override
    public void updatesaleable(Long id, Boolean saleable) {
        Spu spu = new Spu();
        spu.setId(id);
        spu.setSaleable(saleable);
        boolean b = updateById(spu);
        if (!b) {
            throw new LyException(500, "更新失败");
        }

        boolean update = skuService.update().eq("spu_id", id).set("saleable", saleable).update();
        if (!update) {
            throw new LyException(500, "更新失败");
        }
    }
}